package com.yuyou.fn.educational.service.impl;

import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.Principals;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.common.util.Utils;
import com.yuyou.fn.educational.entity.AttendClassRecord;
import com.yuyou.fn.educational.entity.AttendClassRecordDetail;
import com.yuyou.fn.educational.entity.ClassLecture;
import com.yuyou.fn.educational.entity.ShiftClassRecord;
import com.yuyou.fn.educational.mapper.ShiftClassRecordMapper;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.educational.vo.AttendClassRecordDetailQueryVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 *
 * ShiftClassRecord 表数据服务层接口实现类
 *
 */
@Service
public class ShiftClassRecordServiceImpl extends SuperServiceImpl<ShiftClassRecordMapper, ShiftClassRecord,Long> implements IShiftClassRecordService {


    @Resource
    private IAttendClassRecordService attendClassRecordService ;

    @Resource
    private IClassLectureService classLectureService;

    @Resource
    private IStudentRegService studentRegService;

    @Resource
    private IAttendClassRecordDetailService attendClassRecordDetailService;

    @Override
    public List<ShiftClassRecord> findShiftClassRecordByFrom(List<Long> fromAttendClassRecordIds) {
        if (Utils.checkListEmpty(fromAttendClassRecordIds)){
            return Collections.EMPTY_LIST;
        }
        Example<ShiftClassRecord> example=ShiftClassRecord.createExample();
        example.createCriteria().andIn("fromAttendClassRecordId",fromAttendClassRecordIds);
        return this.findListByExample(example);
    }

    /**
     * 1、检查是否能调调班
     * 2、检查目标班是否能调进
     * 3、检查时间是否有冲突
     * @param fromAttendClassRecordId
     * @param destClassLectureId
     * @param remark
     */
    @Transactional
    @Override
    public void saveShiftClass(Long fromAttendClassRecordId, Long destClassLectureId , String remark, Principals.Principal principal) {

        AttendClassRecord fromAttendClassRecord = attendClassRecordService.findById(fromAttendClassRecordId);
        ClassLecture destClassLecture = classLectureService.findById(destClassLectureId);

        saveShiftClass(fromAttendClassRecord, destClassLecture ,remark, principal);


    }

    @Transactional
    @Override
    public void saveShiftClass(AttendClassRecord fromAttendClassRecord, ClassLecture destClassLecture ,String remark, Principals.Principal principal) {



        if(fromAttendClassRecord.getAttendanceStatus() == 1 && fromAttendClassRecord.getAttendanceStatus() == 0  ){
            throw new BusException("已经出勤，不能调班");
        }

        if(destClassLecture.getAttendanceStatus() == 1 ){
            throw new BusException("调进班级讲次已考勤");
        }

        Long classId=fromAttendClassRecord.getClassId();
        Long studentId=fromAttendClassRecord.getStudentId();
        this.checkCanShift(classId,studentId);
        AttendClassRecordDetailQueryVo attendClassRecordDetailQueryVo=new AttendClassRecordDetailQueryVo();
        attendClassRecordDetailQueryVo.setStudentId(studentId);
        attendClassRecordDetailQueryVo.setClassLectureId(destClassLecture.getClassLectureId());
        List<AttendClassRecordDetail> attendClassRecordDetailList=attendClassRecordDetailService.findAttendClassRecordDetailByQueryVo(Arrays.asList(0,2),attendClassRecordDetailQueryVo);

        if (Utils.checkListNotEmpty(attendClassRecordDetailList)){
            throw new BusException("目标讲次已在读");
        }


        fromAttendClassRecord.setShiftStatus(1);//调出
        fromAttendClassRecord.setRemark(remark);
        attendClassRecordService.updateSelectiveById(fromAttendClassRecord);

        AttendClassRecord toAttendClassRecord = new AttendClassRecord();
        toAttendClassRecord.setShiftStatus(2);//调入
        toAttendClassRecord.setFinanceFlag(0);
        toAttendClassRecord.setIsAttendance(0);
        toAttendClassRecord.setAttendanceStatus(0);
        toAttendClassRecord.setClassId(destClassLecture.getClassId());
        toAttendClassRecord.setStudentId(fromAttendClassRecord.getStudentId());
        toAttendClassRecord.setStudentName(fromAttendClassRecord.getStudentName());
        toAttendClassRecord.setClassLectureId(destClassLecture.getClassLectureId());
        toAttendClassRecord.setUpdateTime(TimeUtils.now());
        toAttendClassRecord.setCreateTime(TimeUtils.now());
        try{
            attendClassRecordService.insertSelective(toAttendClassRecord);
        }catch (Exception e){
            throw new BusException("目标班级有报过名，请确认");
        }

        ClassLecture fromClassLecture = classLectureService.findById(fromAttendClassRecord.getClassLectureId());

        //save log
        ShiftClassRecord shiftClassRecord = new ShiftClassRecord();
        shiftClassRecord.setFromAttendClassRecordId(fromAttendClassRecord.getAttendClassRecordId());
        shiftClassRecord.setToAttendClassRecordId(toAttendClassRecord.getAttendClassRecordId());
        shiftClassRecord.setFromClassId(fromAttendClassRecord.getClassId());
        shiftClassRecord.setToClassId(destClassLecture.getClassId());
        shiftClassRecord.setStudentId(fromAttendClassRecord.getStudentId());
        shiftClassRecord.setStudentName(fromAttendClassRecord.getStudentName());
        shiftClassRecord.setToClassLectureNo(destClassLecture.getLectureNo());
        shiftClassRecord.setFromClassLectureNo(fromClassLecture.getLectureNo());
        shiftClassRecord.setOperator(principal.name);
        shiftClassRecord.setCreateTime(TimeUtils.now());
        shiftClassRecord.setUpdateTime(TimeUtils.now());
        insertSelective(shiftClassRecord);

        classLectureService.updateTotalAmount(Arrays.asList(fromAttendClassRecord.getClassLectureId(),destClassLecture.getClassLectureId()));
    }

    @Override
    public void checkCanShift(Long classId, Long studentId) {
        Long shiftCount=this.countByStudentIdClassId(studentId,classId);
        if (shiftCount>=5){
            throw new BusException("同个班级，临时调课的次数最高为5次！");
        }
    }

    @Transactional
    @Override
    public void cancelShiftClass(Long shiftClassRecordId) {
        ShiftClassRecord shiftClassRecord = findById(shiftClassRecordId);
        Long num=this.countByFromId(shiftClassRecord.getToAttendClassRecordId());
        if (num>0l){
            throw new BusException("请先取消该学生最新调课记录");
        }
        List<AttendClassRecord> attendClassRecords = attendClassRecordService.findByIds(Arrays.asList(shiftClassRecord.getFromAttendClassRecordId(), shiftClassRecord.getToAttendClassRecordId()));
        List<Long> classLectureIds = BeanUtils.toList(attendClassRecords,"classLectureId");
        List<ClassLecture> classLectures = classLectureService.findByIds(classLectureIds);
        for(ClassLecture classLecture : classLectures){
            if(classLecture.getAttendanceStatus() != 0 ){
                throw new BusException("新班级/原班级已经考勤，无法撤回！");
            }
        }

        AttendClassRecord attendClassRecord = new AttendClassRecord();
        attendClassRecord.setAttendClassRecordId(shiftClassRecord.getFromAttendClassRecordId());
        attendClassRecord.setShiftStatus(0);
        attendClassRecord.setRemark(StringUtils.EMPTY);
        attendClassRecordService.updateSelectiveById(attendClassRecord);

        attendClassRecordService.deleteById(shiftClassRecord.getToAttendClassRecordId());
        classLectureService.updateTotalAmount(classLectureIds);

        deleteById(shiftClassRecordId);
    }

    @Override
    public Long countByStudentIdClassId(Long studentId, Long classId) {
        if (studentId==null || classId==null){
            return 0L;
        }

        Example<ShiftClassRecord> shiftClassRecordExample=ShiftClassRecord.createExample();
        shiftClassRecordExample.createCriteria().andEqualTo("studentId",studentId).andEqualTo("fromClassId",classId);
        return countByExample(shiftClassRecordExample);
    }

    @Override
    public Long countByStudentIdDestLectureId(Long studentId, Long toAttendClassRecordId) {
        if (studentId==null || toAttendClassRecordId==null){
            throw new NullPointerException();
        }

        Example<ShiftClassRecord> shiftClassRecordExample=ShiftClassRecord.createExample();
        shiftClassRecordExample.createCriteria().andEqualTo("studentId",studentId).andEqualTo("toAttendClassRecordId",toAttendClassRecordId);
        return countByExample(shiftClassRecordExample);
    }

    @Override
    public Long countByFromId(Long fromAttendClassRecordId) {
        Example<ShiftClassRecord> example=ShiftClassRecord.createExample();
        example.createCriteria().andEqualTo("fromAttendClassRecordId",fromAttendClassRecordId);
        return this.countByExample(example);
    }
}